/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_Studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "stdafx.h"
#include "节点.h"
#include "节点树.h"
#include "socket_utils.h"
#include "字符串数值互换.h"
#include "节点数据声明.h"
#include "Context/当前默认操作数据.h"

#include <set>
#include <JIT.h>
#include <mutex>
using namespace std;


static std::list<C_插座基类*> g待销毁插座;




static void f_插座重复名称修改(std::vector<C_插座基类*>& 插座组, C_插座基类* socket) {
	uint32 num = 插座组.size();
	bool 跳出 = true;
	std::wstring name = socket->m_identifier;
	for (uint32 i = 0; i < num; ++i) {
		for (auto& e : 插座组) {
			if (name == e->m_identifier) {
				name += f_整数值转宽字符串(i);
				跳出 = false;
			}
		}

		if (跳出) {
			break;
		}
	}
	socket->m_identifier = name;
}




C_插座基类::C_插座基类(wstring name, E_值类型 type) : m_Type(type) {
	m_联通 = true;
	m_有新数据 = true;
	m_映射指针 = false;
	m_回写插座 = false;
	//m_p连接到输出插座 = nullptr;
	//m_连接线_In口 = nullptr;
	on_UI更新 = nullptr;
	m_UI部件 = nullptr;
	

	m_更新方式 = E_节点更新方式::e_节点更新_被动;
	
	m_pNode = nullptr;
	m_identifier = name;
	m_Name = name;
	m_是否单输入插座 = true;
	m_JIT参数ID = 0;
	
	//m_GPU内存偏移 = -1;
	m_GPU缓存 = {nullptr, 0};
}

C_插座基类::~C_插座基类() {
	m_identifier = L"";
	m_UI部件 = nullptr;

	m_p当前输出插座绑定连接线.clear();
	
}

bool C_插座基类::f_isLink() {
	return bool(m_p当前输出插座绑定连接线.size());

	if (m_是否单输入插座) {
		return bool(m_p当前输出插座绑定连接线.size());
	}

	return false;
}

bool C_插座基类::f_是否联通() {
	return m_联通;
}

bool C_插座基类::f_Link(S_NodeLink* link) {
	
	uint32 线Offset = 0;
	uint32 num = m_p当前输出插座绑定连接线.size();
	if (!m_是否为输出插座) {
		m_有新数据 = true;
	}
	m_p当前输出插座绑定连接线.push_back(link);
	//m_pNode->m_Tree->m_节点结构改变 = true;
	m_pNode->f_更新上层节点(true);
	return true;
}

void C_插座基类::f_断开输出链接(S_NodeLink* link) {
	uint32 num = m_p当前输出插座绑定连接线.size();
	m_有新数据 = true;

	if (link) {
		for (uint32 i = 0; i < num; ++i) {
			if (m_p当前输出插座绑定连接线[i] == link) {
				//link->m_插座in->m_p当前输出插座绑定连接线[0];

				m_p当前输出插座绑定连接线.erase(m_p当前输出插座绑定连接线.begin() + i);
				m_pNode->f_get所在节点树()->m_节点结构改变 = true;
				m_pNode->f_更新上层节点(true);


				if (!m_是否为输出插座) {
					m_pNode->f_set是否要更新(true);

					auto& links = link->m_插座out->f_getLinkLines();
					uint32 链接数量 = links.size();
					for (uint32 j = 0; j < 链接数量; ++j) {
						if (links[j] == link) {
							links.erase(links.begin() + j);
							break;
						}
					}
				}

				return;
			}
		}
	}
	else {
		for (uint32 i = 0; i < num; ++i) {
			auto* 当前链接线 = m_p当前输出插座绑定连接线[i];

			m_pNode->f_get所在节点树()->m_节点结构改变 = true;
			m_pNode->f_更新上层节点(true);

			if (!m_是否为输出插座) {
				m_pNode->f_set是否要更新(true);

				auto& links = 当前链接线->m_插座out->f_getLinkLines();
				uint32 链接数量 = links.size();
				for (uint32 j = 0; j < 链接数量; ++j) {
					if (links[j] == 当前链接线) {
						links.erase(links.begin() + j);
						break;
					}
				}
			}
		}
		m_p当前输出插座绑定连接线.clear();
	}
}





C_插座基类* C_插座基类::f_getLinkOutSocket(uint16 插座) {
	if (!m_是否为输出插座) {
		if (插座 < m_p当前输出插座绑定连接线.size()) {
			auto type = m_p当前输出插座绑定连接线[插座]->m_插座out->m_pNode->m_Type;
			switch (type) {
				case e_节点Type_Reroute: {
					auto socket = m_p当前输出插座绑定连接线[插座]->m_插座out->m_pNode->f_get输入插座(1);
					if (socket == this) {
						return m_p当前输出插座绑定连接线[插座]->m_插座out;
					}
					return socket->f_getLinkOutSocket();
				}
				
				
			
			/*case e_节点Type_组输入: {
				auto root_node = m_p当前输出插座绑定连接线[插座]->m_插座out->m_pNode->m_Tree->f_get父节点();
				int16 插座位置 = m_pNode->f_get输入插座Loc(this);
				return m_p当前输出插座绑定连接线[插座]->m_插座out->m_pNode->m_Tree->f_get父节点()->f_get输入插座(插座位置)->f_getLinkOutSocket(插座);
			}*/
			//case e_节点Type_组输出:
				//m_p当前输出插座绑定连接线[插座]->m_插座out->m_pNode->m_Tree->f_get父节点()->f_get输入插座(插座)->f_getLinkOutSocket();
			//	break;

				default:
					return m_p当前输出插座绑定连接线[插座]->m_插座out;
			}
		}
	}
	return nullptr;
}

std::vector<C_插座基类*> C_插座基类::f_getLinkOutSocketGroup() {
	std::vector<C_插座基类*> sockets;
	if (!m_是否为输出插座) {
		for (auto& e : m_p当前输出插座绑定连接线) {
			if (e->m_插座out->m_pNode->m_Type == E_节点类型::e_节点Type_Reroute) {
				auto 上级插座 = e->m_插座out->m_pNode->f_get输入插座(0)->f_getLinkOutSocketGroup();
				sockets.insert(sockets.end(), 上级插座.begin(), 上级插座.end());
			}
			else {
				sockets.push_back(e->m_插座out);
			}
		}
	}
	return sockets;
}

void* C_插座基类::f_getData(uint8 插座) {
	C_插座基类* socket = f_getLinkOutSocket();
	if (socket) {
		return socket->f_getData(0);
	}
	return &m_联通;
}

inline E_JIT_FunParam C_插座基类::f_getJIT参数(uint8 线程ID, uint16 in_ID) {
	m_JIT参数ID = in_ID;
	E_JIT_FunParam 参数;

	参数.m_data = f_getData(线程ID);
	参数.m_type = m_Type;
	参数.m_Num = 0;
	return 参数;
}




bool C_插座基类::f_getBool(const uvec4& id) {
	C_插座基类* ps = f_getLinkOutSocket();
	if (ps) {
		return ps->f_getBool(id);
	}
	return m_联通;
}

S_GPU内存块索引& C_插座基类::f_getGPU块(uint8 线程ID, bool 更新) {
	if (!m_GPU缓存.m_Buf) {
		//m_GPU缓存 = f_buf_alloc(f_NodeCtx_get默认场景()->m_光追后端->m_Vec3动态属性, 1);
	}
	return m_GPU缓存;
}

S_GPU内存块索引& C_插座基类::f_downGPU块(uint8 线程ID, bool 更新) {
	return m_GPU缓存;
}



std::string C_插座基类::f_构建变量代码(int32 loc) {
	std::string code;
	auto* rt = f_getNode()->f_getThis节点树();

	switch (rt->m_树类型) {
	case E_节点树类型::e_type_着色节点树: {
		if (m_GPU缓存.m_Mem.m_大小 >= 0) {
			switch (m_Type) {
			case E_值类型::e_Type_F32: {
				m_Code = "f32_GParam.f32Ptr[" + f_整数值转字符串(m_GPU缓存.m_Mem.m_偏移) + "]";
				break;
			}
			case E_值类型::e_Type_I32: {
				m_Code = "i32_GParam.i32Ptr[" + f_整数值转字符串(m_GPU缓存.m_Mem.m_偏移) + "]";
				break;
			}
			case E_值类型::e_Type_Vec2: {
				m_Code = "vec2_GParam.vec2Ptr[" + f_整数值转字符串(m_GPU缓存.m_Mem.m_偏移) + "]";
				break;
			}
			case E_值类型::e_Type_Vec3: {
				m_Code = "vec3_GParam.vec3Ptr[" + f_整数值转字符串(m_GPU缓存.m_Mem.m_偏移) + "]";
				break;
			}
			default:
				break;
			}
		}
		break;
	}
	default: {
		rt->g_分配内存锁.lock();
		{
			auto& JIT参数 = rt->m_JIT二级参数;
			uint16 常量ID = JIT参数.size();
			//if (rt->m_参数全局偏移 == 3 && 常量ID == 8) {
			//	std::cout<<"节点全局变量内存分配"<<std::endl;
			//}
			m_Code = "(*(" + f_node_getDataTypeName(m_Type) + "*)(" + DEF_S(DEF_编译全局可调参数名称) + "[" + f_整数值转字符串(rt->m_参数全局偏移) + "][" + f_整数值转字符串(常量ID) + "]))";
			JIT参数.push_back(f_getData(0));
		}
		rt->g_分配内存锁.unlock();
		break;
	}
	}
	return code;
}

//std::string C_插座基类::f_构建变量代码(int32 多输入ID) {
//	std::string code;
//	auto* rt = f_getNode()->f_getThis节点树();
//
//	if (多输入ID >= m_多输入代码.size()) {
//		m_多输入代码.resize(多输入ID + 1);
//	}
//
//	switch (rt->m_树类型) {
//		case E_节点树类型::e_type_着色节点树: {
//			if (m_GPU缓存.m_Mem.m_大小 >= 0) {
//				switch (m_Type) {
//					case E_值类型::e_Type_F32: {
//						m_多输入代码[多输入ID] = "f32_GParam.f32Ptr[" + f_整数值转字符串(m_GPU缓存.m_Mem.m_偏移) + "]";
//						break;
//					}
//					case E_值类型::e_Type_I32: {
//						m_多输入代码[多输入ID] = "i32_GParam.i32Ptr[" + f_整数值转字符串(m_GPU缓存.m_Mem.m_偏移) + "]";
//						break;
//					}
//					case E_值类型::e_Type_Vec2: {
//						m_多输入代码[多输入ID] = "vec2_GParam.vec2Ptr[" + f_整数值转字符串(m_GPU缓存.m_Mem.m_偏移) + "]";
//						break;
//					}
//					case E_值类型::e_Type_Vec3: {
//						m_多输入代码[多输入ID] = "vec3_GParam.vec3Ptr[" + f_整数值转字符串(m_GPU缓存.m_Mem.m_偏移) + "]";
//						break;
//					}
//					default:
//						break;
//				}
//			}
//			break;
//		}
//		default: {
//			rt->g_分配内存锁.lock();
//			{
//				auto& JIT参数 = rt->m_JIT二级参数;
//				uint16 常量ID = JIT参数.size();
//				m_多输入代码[多输入ID] = "(*(" + f_node_getDataTypeName(m_Type) + "*)(" + DEF_S(DEF_编译全局可调参数名称) + "[" + f_整数值转字符串(rt->m_参数全局偏移) + "][" + f_整数值转字符串(常量ID) + "]))";
//
//				JIT参数.push_back(f_getData(0));
//			}
//			rt->g_分配内存锁.unlock();
//			break;
//		}
//	}
//	return code;
//}

std::string C_插座基类::f_getName() {
	switch (m_pNode->f_get所在节点树()->m_树类型) {
	case E_节点树类型::e_type_着色节点树:
		return f_str_汉字字符串转拼音(m_identifier);
	default:
		break;
	}
	return f_WStringToString(m_identifier);
}

void C_插座基类::f_setData(void *data, uint8 线程ID) {
	if (data) {
		m_联通 = *((bool*)data);
		m_有新数据 = true;
	}
	else {
		
	}
}


wstring C_插座基类::f_get所在节点名称() {
	return m_pNode->f_getWName();
}

std::vector<C_节点基类*> C_插座基类::f_get链接到的输出插座节点() {
	std::vector<C_节点基类*> outData;
	if (!m_是否为输出插座) {
		if (m_p当前输出插座绑定连接线.size()) {
			for (auto link : m_p当前输出插座绑定连接线) {
				auto out插座 = link->m_插座out;
				//if (out插座->m_pNode->m_Type == E_节点类型::e_节点Type_Reroute) {
				//	auto t = out插座->m_pNode->f_get输入插座(1)->f_get链接到的输出插座节点();
				//
				//	for(auto 上层节点 : t) outData.push_back(上层节点);
				//}
				//else {
				//	outData.push_back(out插座->m_pNode);
				//}
				if (out插座) {
					outData.push_back(out插座->m_pNode);
				}
				else {
					std::cout<<"error : 链接线没有输出插值指针"<<std::endl;
				}
			}
		}
	}
	return outData;
}

std::vector<C_插座基类*> C_插座基类::f_get链接到的输出插座() {
	std::vector<C_插座基类*> outData;
	for (auto link : m_p当前输出插座绑定连接线) {
		outData.push_back(link->m_插座out);
	}
	return outData;
}


vector<C_节点基类*> C_插座基类::f_get链接到的输入插座节点() {
	vector<C_节点基类*> outSocketsNodes;

	auto inSocket = f_get链接到的输入插座();
	for (auto& s : inSocket) {
		outSocketsNodes.push_back(s->m_pNode);
	}

	return outSocketsNodes;
}

vector<C_插座基类*> C_插座基类::f_get链接到的输入插座() {
	if (m_p当前输出插座绑定连接线.size() > 65536) {
		m_p当前输出插座绑定连接线.clear();
		std::cout << "error : 取链接的输入插座异常" << std::endl;
		return {};
	}

	vector<C_插座基类*> outSockets;

	for (auto link : m_p当前输出插座绑定连接线) {
		auto* 当前迭代in插座 = link->m_插座in;
		if (!当前迭代in插座->m_pNode) {
			m_p当前输出插座绑定连接线.clear();
			std::cout<<"error: 链接到的输入插座 链接线没有绑定节点"<< 当前迭代in插座->m_pNode << std::endl;
			continue;
		}
		if (当前迭代in插座->m_pNode->m_Type == E_节点类型::e_节点Type_Reroute) {
			auto sockets = 当前迭代in插座->m_pNode->f_get输出插座(0)->f_get链接到的输入插座();
			outSockets.insert(outSockets.end(), sockets.begin(), sockets.end());
		}
		else {
			outSockets.push_back(link->m_插座in);
		}
	}

	return outSockets;
}

vector<C_插座基类*> C_插座基类::f_get直接链接到的输入插座() {
	vector<C_插座基类*> outSockets;

	for (auto link : m_p当前输出插座绑定连接线) {
		auto* 当前迭代in插座 = link->m_插座in;
		outSockets.push_back(link->m_插座in);
	}

	return outSockets;
}

E_值类型 C_插座基类::f_get接入的数据类型(int32 loc) {
	C_插座基类* outSocket = f_getLinkOutSocket(loc);
	if (outSocket) {
		if (outSocket->m_Type == E_值类型::e_Type_Array) {

		}
		return outSocket->m_Type;
	}
	return m_Type;
}

C_插座基类* C_插座基类::f_get输出数据的插座() {
	C_插座基类* outSocket = f_getLinkOutSocket();
	return outSocket;
}

std::string C_插座基类::f_getCode(int32 loc) {
	return m_Code;
	//std::string code;
	//switch (m_Type)
	//{
	//case E_值类型::e_Type_I32:
	//	code += "int32";
	//default:
	//	break;
	//}
	//code += " " + f_WStringToString(m_identifier);
	//return code;
}

/*uint16 C_插座基类::f_get输入插座连接到输出插座数据位置(C_插座基类* inSocket) {
	uint16 pos = 0;
	for (auto& e : m_p连接到输入插座) {
		if (inSocket == e) {
			return pos;
		}
		++pos;
	}
	return 0xffff;
}*/

std::vector<void*> C_插座基类::f_get属性数据(E_值类型 type) {
	std::vector<void*> r;

	for (auto& e : m_附带属性) {
		if (e.m_Type = type) {
			r.push_back(e.m_DataPoint);
		}
	}
	return r;
}




void C_插座基类::f_读取(FILE* f) {
	fread(&m_是否为输出插座, sizeof(bool), 1, f);
	fread(&m_是否单输入插座, sizeof(bool), 1, f);

	m_identifier = f_file_读取字符串(f);
}

void C_插座基类::f_写入(FILE* f) {
	fwrite(&m_是否为输出插座, sizeof(bool), 1, f);
	fwrite(&m_是否单输入插座, sizeof(bool), 1, f);

	f_file_保存字符串(f, m_identifier);
}












C_节点基类::C_节点基类(std::string typeName, E_节点类型 type) :
	m_TypeName(typeName),
	m_Type(type),
	
	m_层(0),
	m_并发(true),
	m_子集节点树(nullptr),
	m_ThisTree(nullptr),
	//m_父节点(nullptr),
	m_当前节点所在节点树(nullptr),
	m_耗时(0.0),
	m_数据布局(E_节点数据布局::e_局部)
	, m_框节点(nullptr)
{
	//f_set设置绑定的BL节点(m_blNode);
	m_更新方式				 = E_节点更新方式::e_节点更新_被动;
	m_是否要更新			 = true;
	m_越过更新               = false;
	m_冻结数据               = false;
	m_显示数据               = true;
	m_节点层级结构更新		 = true;
	m_外部更新Bl节点		 = false;
	m_是否释放数据			 = false;
	m_插座改变后是否更新节点 = false;
	m_区域父节点 = nullptr;
	m_标记区域 = false;

	m_坐标		 = {};
	m_是否有焦点 = false;
	m_插座可编辑 = false;

	m_耗时		 = 0.0;
	m_更新时间   = 0;

	mf_编译 = nullptr;
	m_编译成功 = true;
	

	//if (m_Type != E_节点类型::e_节点Type_Reroute) {
		C_插座基类* socket1 = new C_插座基类(L"_>", E_值类型::e_Type_Bool);
		C_插座基类* socket2 = new C_插座基类(L"_<", E_值类型::e_Type_Bool);
		socket1->f_set多输入();

		f_add插座(socket1, e_插座Type_输入);
		f_add插座(socket2, e_插座Type_输出);
	//}
	
	m_ICO = "";



	m_启用 = f_alloc_BoolProp(nullptr, L"启用");
	m_启用.m_私有 = true;
	f_prop_Bool(m_启用) = true;

}

C_节点基类::~C_节点基类() {
	m_区域内节点.clear();
	m_包含在多个视口的UI部件.clear();

	if (m_子集节点树) {
		m_子集节点树->m_节点树绑定的父节点.erase(this);
	}
	m_子集节点树 = nullptr;
	

	set<C_节点基类*> 右下游节点;
	for (auto& socket : m_outputs) {
		auto 下游节点 = socket->f_get链接到的输入插座节点();
		for (auto& node : 下游节点) {
			node->f_set是否要更新(true);
		}
		socket->f_断开输出链接(nullptr);
	}

	for (auto& e : m_inputs) {
		delete e;
	}
	for (auto& e : m_outputs) {
		delete e;
	}
	m_inputs.clear();
	m_outputs.clear();

}

void C_节点基类::f_add插座(C_插座基类* socket, E_插座方向 方向, int32 loc) {
	switch (方向) {
		case e_插座Type_输入: {
			socket->m_是否为输出插座 = false;
			if (loc >= m_inputs.size()) {
				m_inputs.push_back(socket);
			}
			else {
				m_inputs.insert(m_inputs.begin() + loc, socket);
			}

			f_插座重复名称修改(m_inputs, socket);
			break;
		}
		
		case e_插座Type_输出: {
			socket->m_是否为输出插座 = true;
			if (loc >= m_outputs.size()) {
				m_outputs.push_back(socket);
			}
			else {
				m_outputs.insert(m_outputs.begin() + loc, socket);
			}

			f_插座重复名称修改(m_outputs, socket);
			break;
		}
		
	default:
		break;
	}
	//cout << "socket = " << socket << " = " << this << endl;
	socket->m_pNode = this;
	
	f_更新上层节点(true);
}

uint16 C_节点基类::f_get输出插座连接数量() {
	uint16 linkNum = 0;
	
	for (auto& e : m_outputs) {
		linkNum += e->m_p当前输出插座绑定连接线.size();
	}
	return linkNum;
}

uint16 C_节点基类::f_get多输入插座数量() {
	uint16 num = 0;
	for (auto& e : m_inputs) {
		if (!(e->m_是否单输入插座)) ++num;
	}
	return num - 1;
}

void C_节点基类::f_替换插座(C_插座基类* 新socket, uint16 loc, E_插座方向 方向) {
	新socket->m_pNode = this;


	if (方向 == E_插座方向::e_插座Type_输入) {
		if (loc < m_inputs.size()) {
			新socket->m_是否为输出插座 = false;
			if (m_inputs[loc]->m_p当前输出插座绑定连接线.size()) {
				
				uint32 插座数量 = m_inputs[loc]->m_p当前输出插座绑定连接线.size();
				for (uint32 i = 0; i < 插座数量; ++i) {
					if (m_inputs[loc] == m_inputs[loc]->m_p当前输出插座绑定连接线[i]->m_插座in) {
						m_inputs[loc]->m_p当前输出插座绑定连接线[i]->m_插座in = 新socket;
					}
				}
			}
			
			//绑定的UI组件 拷贝
			新socket->m_是否单输入插座          = m_inputs[loc]->m_是否单输入插座;
			新socket->m_UI部件                  = m_inputs[loc]->m_UI部件;
			新socket->on_UI更新                 = m_inputs[loc]->on_UI更新;
			新socket->m_p当前输出插座绑定连接线 = m_inputs[loc]->m_p当前输出插座绑定连接线;

			新socket->m_GPU缓存                 = m_inputs[loc]->m_GPU缓存;
			//新socket->m_GPU内存偏移             = m_inputs[loc]->m_GPU内存偏移;
			//if (新socket->on_UI更新) 新socket->on_UI更新(新socket);
			f_node_移除插座准备销毁(m_inputs[loc]);
			//delete m_inputs[loc];
			m_inputs[loc] = 新socket;
		}
		else {
			f_add插座(新socket, 方向);
		}
	}
	else {
		if (loc < m_outputs.size()) {
			新socket->m_是否为输出插座 = true;
			for (auto* 输入插座 : m_outputs[loc]->m_p当前输出插座绑定连接线) {
				uint32 插座数量 = m_outputs[loc]->m_p当前输出插座绑定连接线.size();

				for (uint32 i = 0; i < 插座数量; ++i) {
					if (m_outputs[loc] == m_outputs[loc]->m_p当前输出插座绑定连接线[i]->m_插座out) {
						m_outputs[loc]->m_p当前输出插座绑定连接线[i]->m_插座out = 新socket;
					}
				}
			}

			//绑定的UI组件 拷贝
			新socket->m_是否单输入插座          = m_outputs[loc]->m_是否单输入插座;
			新socket->m_UI部件                  = m_outputs[loc]->m_UI部件;
			新socket->on_UI更新                 = m_outputs[loc]->on_UI更新;
			新socket->m_p当前输出插座绑定连接线 = m_outputs[loc]->m_p当前输出插座绑定连接线;

			新socket->m_GPU缓存                 = m_outputs[loc]->m_GPU缓存;
			//新socket->m_GPU内存偏移             = m_outputs[loc]->m_GPU内存偏移;
			//if(新socket->on_UI更新) 新socket->on_UI更新(新socket);
			f_node_移除插座准备销毁(m_outputs[loc]);
			//delete m_outputs[loc];
			m_outputs[loc] = 新socket;
		}
		else {
			f_add插座(新socket, 方向);
		}
	}

	if (新socket->on_UI更新) 新socket->on_UI更新(新socket);
	
	return;
}

void C_节点基类::f_替换插座(vector<C_插座基类*>& sockets, E_插座方向 方向) {
	if (方向 == E_插座方向::e_插座Type_输入) {
		m_inputs = sockets;
	} else {
		m_outputs = sockets;
	}
}









void C_节点基类::f_del插座(const wstring name, E_插座方向 方向) {
	int16 sNum = -1;
	C_插座基类** s = 0;

	if (方向 == E_插座方向::e_插座Type_输入) {
		sNum = m_inputs.size();
		s = m_inputs.data();
	} else {
		sNum = m_outputs.size();
		s = m_outputs.data();
	}

	for (uint16 i = 0; i < sNum; ++i) {
		if (s[i]->m_identifier == name) {
			sNum = i; break;
		}
	}

	if (sNum >= 0) {
		f_del插座(sNum, 方向);
	}

	f_更新上层节点(true);
	//if (m_Tree) {
	//	m_Tree->m_节点结构改变 = true;
	//}
}

void C_节点基类::f_del插座(uint32 loc, E_插座方向 方向) {
	f_更新上层节点(true);

	if (方向 == E_插座方向::e_插座Type_输入) {
		if (m_inputs.size() <= 1 || !loc) {
			return;
		}
		if (loc >= m_inputs.size()) {
			loc = m_inputs.size() - 1;
		}

		uint32 num = m_inputs[loc]->m_p当前输出插座绑定连接线.size();
		for (uint32 i = 0; i < num; ++i) {
			if (m_inputs[loc]->m_p当前输出插座绑定连接线.size()) {
				auto& link = m_inputs[loc]->m_p当前输出插座绑定连接线.front();
				link->f_断开输出链接();
			}
			else break;
		}
		//for (auto link : m_inputs[loc]->m_p当前输出插座绑定连接线) {
		//	link->f_断开输出链接();
		//}
		delete m_inputs[loc];
		m_inputs.erase(m_inputs.begin() + loc);
	}
	else {
		if (m_outputs.size() <= 1 || !loc) {
			return;
		}
		if (loc >= m_outputs.size()) {
			loc = m_outputs.size() - 1;
		}
		
		uint32 num = m_outputs[loc]->m_p当前输出插座绑定连接线.size();
		for (uint32 i = 0; i < num; ++i) {
			if (m_outputs[loc]->m_p当前输出插座绑定连接线.size()) {
				auto& link = m_outputs[loc]->m_p当前输出插座绑定连接线.front();
				link->f_断开输出链接();
			}
			else break;
		}
		//for (auto link : m_outputs[loc]->m_p当前输出插座绑定连接线) {
		//	link->f_断开输出链接();
		//}
		delete m_outputs[loc];
		m_outputs.erase(m_outputs.begin() + loc);
	}

	auto* t = f_get子集树();
	if (t) {
		t->m_节点结构改变 = true;
	}
}


bool C_节点基类::f_释放插座数据(E_插座方向 方向) {
	if (方向 == E_插座方向::e_插座Type_输入) {
		for (auto& socket : m_inputs) socket->f_释放数据();
	} else if (方向 == E_插座方向::e_插座Type_输出) {
		for (auto& socket : m_outputs) socket->f_释放数据();
	}
	return false;
}

bool C_节点基类::f_移动插座(E_插座方向 方向, E_方向 上下, int16 step) {
	if (step <= 0) return false;

	C_插座基类** sockets = 0;
	uint32 num = 0;
	if (方向 == E_插座方向::e_插座Type_输入) {
		sockets = m_inputs.data();
		num = m_inputs.size();
	} else {
		sockets = m_outputs.data();
		num = m_outputs.size();
	}

	if (上下 == E_方向::e_上) {
		auto* temp = sockets[step - 1];
		sockets[step - 1] = sockets[step];
		sockets[step] = temp;
	}
	else {
		if (step + 1 < m_inputs.size()) {
			auto* temp = sockets[step + 1];
			sockets[step + 1] = sockets[step];
			sockets[step] = temp;
		}
		else return false;
	}
	return true;
}

void C_节点基类::f_Copy(const C_节点基类* node) {
}

std::string C_节点基类::f_getName() {
	switch (m_当前节点所在节点树->m_树类型) {
	case E_节点树类型::e_type_着色节点树:
		return f_str_汉字字符串转拼音(m_Name);
	default:
		break;
	}
	return f_WStringToString(m_Name);
}

std::string C_节点基类::f_编译(C_节点基类* rn, std::string& 声明, std::vector<std::string>& 定义, std::string& 释放) {
	if (mf_编译) {
		return mf_编译(this, 声明, 定义, 释放);
	}
	return ""; 
}

void C_节点基类::f_绑定子集节点树(C_节点树* tree) {
	m_子集节点树 = tree;
	m_子集节点树->m_节点树绑定的父节点.insert(this);
}

void C_节点基类::f_解绑定子集节点树() {
	if (m_子集节点树) {
		m_子集节点树->m_节点树绑定的父节点.erase(this);
		m_子集节点树 = nullptr;
	}
}

inline C_节点树* C_节点基类::f_getThis节点树(const C_节点树* 当前节点树) {
	return m_当前节点所在节点树;
	switch (m_当前节点所在节点树->m_树类型) {
	case E_节点树类型::e_type_几何节点树:
	case E_节点树类型::e_type_着色节点树:
	case E_节点树类型::e_type_材质节点树:
		return m_当前节点所在节点树;

	case E_节点树类型::e_type_函数节点树:
		if (m_子集节点树) {
			if (m_当前节点所在节点树 != m_子集节点树) {
				/*for (auto& e : m_当前节点所在节点树->m_节点树绑定的父节点) {
					if (e->m_Type == E_节点类型::e_节点Type_函数) {
						if(e->m_当前节点所在节点树 == e->m_子集节点树) continue;
					}
					auto* t = e->f_getThis节点树();
				}*/
				return m_当前节点所在节点树;
			}
			//return nullptr;
		}
	
	default:
		for (auto& e : m_当前节点所在节点树->m_节点树绑定的父节点) {
			if (e->m_Type == E_节点类型::e_节点Type_函数) {
				if(e->m_当前节点所在节点树 == e->m_子集节点树) continue;
			}
			auto* t = e->f_getThis节点树();
			if (t) return t;
		}
		break;
	}
	/*C_节点基类* node = m_当前节点的子节点树->f_get父节点();
	if (node) {
		return node->f_getThis节点树();
	}
	else {
		return m_ThisTree;
	}*/
	return m_当前节点所在节点树;
}

C_节点基类* C_节点基类::f_getThis节点() {
	switch (m_当前节点所在节点树->m_树类型) {
		case E_节点树类型::e_type_材质节点树:
		case E_节点树类型::e_type_几何节点树:
		case E_节点树类型::e_type_函数节点树:
			return m_当前节点所在节点树->f_get父节点();
		default:
			for (auto& e : m_当前节点所在节点树->m_节点树绑定的父节点) {
				auto* t = e->f_getThis节点();
				if (t) return t;
			}
			break;
	}
	/*C_节点基类* node = m_当前节点的子节点树->f_get父节点();
	if (node) {
		return node->f_getThis节点();
	}
	else {
		if (m_ThisTree) {
			return this;
		}
	}*/
	return nullptr;
}

void C_节点基类::f_set所在节点树(C_节点树* tree) { 
	m_当前节点所在节点树 = tree; 
	if (m_子集节点树) {
		m_子集节点树->m_节点树绑定的父节点.insert(this);
	}

	
}









inline void C_节点基类::f_set是否要更新(bool update) {
	m_是否要更新 = update;

	if (!m_当前节点所在节点树) return;
	for (auto& e : m_当前节点所在节点树->m_节点树绑定的父节点) {
		if (e != this && e->m_当前节点所在节点树 && e->m_是否要更新 == false) {
			e->f_set是否要更新(update);
		}
	}
}

inline void C_节点基类::f_更新上层节点(bool 更新结构) {
	m_是否要更新 = true;

	if (!m_当前节点所在节点树) return;
	m_当前节点所在节点树->m_节点结构改变 = 更新结构;
	m_当前节点所在节点树->m_编译以准备好 = false;

	bool 内联调用 = f_NT_是否内联调用(this);
	if (内联调用) {
		if((m_当前节点所在节点树->m_以编译 & E_节点树编译位标志::e_节点编译_内联调用)) m_当前节点所在节点树->m_以编译 ^= E_节点树编译位标志::e_节点编译_内联调用;
	}
	else {
		if ((m_当前节点所在节点树->m_以编译 & E_节点树编译位标志::e_节点编译_外部调用)) m_当前节点所在节点树->m_以编译 ^= E_节点树编译位标志::e_节点编译_外部调用;
	}


	if(m_子集节点树) {
		//m_子集节点树->m_以编译 = 0;

		if (内联调用) {
			if ((m_子集节点树->m_以编译 & E_节点树编译位标志::e_节点编译_内联调用)) m_子集节点树->m_以编译 ^= E_节点树编译位标志::e_节点编译_内联调用;
		}
		else {
			if ((m_子集节点树->m_以编译 & E_节点树编译位标志::e_节点编译_外部调用)) m_子集节点树->m_以编译 ^= E_节点树编译位标志::e_节点编译_外部调用;
		}

		if (m_子集节点树->m_程序集) {
			f_node_销毁程序集(m_子集节点树);
		}

		//if (m_子集节点树->m_树类型 == E_节点树类型::e_type_着色节点树) return;
	}

	for (auto& e : m_当前节点所在节点树->m_节点树绑定的父节点) {
		

		if (e != this && e->m_当前节点所在节点树) {
			bool 不是递归节点树 = (e->m_当前节点所在节点树 != m_当前节点所在节点树) || (e->m_当前节点所在节点树->m_节点结构改变);
			
			if(不是递归节点树){
				e->m_当前节点所在节点树->m_节点结构改变 = 更新结构;
				e->f_更新上层节点(true);
			}
		}
	}

}

bool C_节点基类::f_上层节点是否以更新() {
	bool 上层节点是否以更新 = true;
	for (const auto& s : m_inputs) {
		for (auto& link : s->m_p当前输出插座绑定连接线) {
			C_节点基类* 上层节点 = link->m_插座out->m_pNode;

			if (上层节点 && 上层节点->f_需要更新()) {
				上层节点是否以更新 = false;
				break;
			}
		}
	}
	return 上层节点是否以更新;
}

bool C_节点基类::f_上层节点层级结构是否以更新() {
	bool 上层节点层级结构是否以更新 = true;
	
	for (const auto& s : m_inputs) {
		for (auto& link : s->m_p当前输出插座绑定连接线) {
			C_节点基类* 上层节点 = link->m_插座out->m_pNode;

			if (上层节点 && 上层节点->f_层级结构需更新()) {
				上层节点层级结构是否以更新 = false;
				break;
			}
		}
	}
	return 上层节点层级结构是否以更新;
}

void C_节点基类::f_输入插座标记已读() {
	for (auto& s : m_inputs) s->m_有新数据 = false;
}

void C_节点基类::f_标记输出插座新数据(uint16 loc, bool f, E_插座方向 方向) {
	if (方向 == E_插座方向::e_插座Type_输入) {
		m_inputs[loc]->m_有新数据 = f;
	}
	else if (方向 == E_插座方向::e_插座Type_输出) {
		m_outputs[loc]->m_有新数据 = f;
	}
}


uint16 C_节点基类::f_get输入插座链接数量() {
	uint16 num = 0;
	uint16 sNum = m_inputs.size();
	for (uint16 i = 0; i < m_inputs.size(); ++i) {
		num += m_inputs[i]->m_p当前输出插座绑定连接线.size();
	}
	return num;
}

uint16 C_节点基类::f_get输出插座链接数量()
{
	uint16 num = 0;
	uint16 sNum = m_outputs.size();
	for (uint16 i = 0; i < m_outputs.size(); ++i) {
		num += m_outputs[i]->m_p当前输出插座绑定连接线.size();
	}
	return num;
}



C_插座基类* C_节点基类::f_get输入插座(const wstring& name) {
	uint16 sNum = m_inputs.size();
	C_插座基类** s = m_inputs.data();
	for (uint16 i = 0; i < sNum; ++i) {
		if (s[i]->m_identifier == name) {
			return s[i];
		}
	}
	return nullptr;
}

C_插座基类* C_节点基类::f_get输出插座(const wstring& name) {
	uint16 sNum = m_outputs.size();
	C_插座基类** s = m_outputs.data();
	for (uint16 i = 0; i < sNum; ++i) {
		if (s[i]->m_identifier == name) {
			return s[i];
		}
	}
	return nullptr;
}






int16 C_节点基类::f_get输入插座Loc(C_插座基类* name) {
	uint16 sNum = m_inputs.size();
	C_插座基类** s = m_inputs.data();
	for (uint16 i = 0; i < sNum; ++i) {
		if (s[i] == name) {
			return i;
		}
	}
	return -1;
}

int16 C_节点基类::f_get输出插座Loc(C_插座基类* name) {
	uint16 sNum = m_outputs.size();
	C_插座基类** s = m_outputs.data();
	for (uint16 i = 0; i < sNum; ++i) {
		if (s[i] == name) {
			return i;
		}
	}
	return -1;
}



int16 C_节点基类::f_get输入插座Loc(const wstring & name) {
	uint16 sNum = m_inputs.size();
	C_插座基类** s = m_inputs.data();
	for (uint16 i = 0; i < sNum; ++i) {
		if (s[i]->m_identifier == name) {
			return i;
		}
	}
	return -1;
}

int16 C_节点基类::f_get输出插座Loc(const wstring & name) {
	uint16 sNum = m_outputs.size();
	C_插座基类** s = m_outputs.data();
	for (uint16 i = 0; i < sNum; ++i) {
		if (s[i]->m_identifier == name) {
			return i;
		}
	}
	return -1;
}


const C_插座基类* C_节点基类::f_get输入插座(uint32 id) const {
	assert(id < m_inputs.size());
	return m_inputs[id];
}

C_插座基类* C_节点基类::f_get输入插座(uint32 id) {
	if (id >= m_inputs.size()) id = m_inputs.size() -1;
	assert(id < m_inputs.size());
	return m_inputs[id];
}

C_插座基类* C_节点基类::f_get输出插座(uint32 id) {
	if (id >= m_outputs.size()) id = m_outputs.size() - 1;
	return m_outputs[id];
}


/*void C_节点基类::f_断开输入链接(uint32 socketID) {
	m_inputs[socketID]->f_断开输出链接();
}*/



void C_节点基类::f_get下层节点(vector<C_节点基类*>& 下层节点) {
	uint16 Num = m_outputs.size();
	C_插座基类** s = m_outputs.data();

	for (uint16 i = 0; i < Num; ++i) {
		if (s[i]->f_isLink() == false) continue;

		for (auto& link : s[i]->m_p当前输出插座绑定连接线) {
			//下层节点.push_back(link->m_插座in->m_pNode);
			下层节点.emplace_back(link->m_插座in->m_pNode);
		}
	}

	std::sort(下层节点.begin(), 下层节点.end());
	下层节点.erase(std::unique(下层节点.begin(), 下层节点.end()), 下层节点.end());
}



void C_节点基类::f_set下层节点为需要更新() {
	uint16 Num = m_outputs.size();
	C_插座基类** s = m_outputs.data();

#pragma omp parallel for num_threads(2)
	for (int16 i = 0; i < Num; ++i) {
		//auto 连接到的in插座 = s[i]->f_get链接到的输入插座();
		auto 连接到的in插座 = s[i]->f_get直接链接到的输入插座();

		//if (s[i]->m_有新数据) {
		C_插座基类** 链接到的输入插座 = 连接到的in插座.data();
		uint16 链接到的输入插座Num = 连接到的in插座.size();

		for (uint16 j = 0; j < 链接到的输入插座Num; ++j) {
			链接到的输入插座[j]->m_pNode->f_set是否要更新(true);
		}
	}
	
}

void C_节点基类::f_set节点更新方式(E_节点更新方式 方式) {
	m_更新方式 = 方式;
}

void C_节点基类::f_构建附属节点(std::map<std::wstring, C_节点基类*>& nodes) {
	m_框包含节点.clear();

	for (auto& e : m_框包含节点名称) {
		if (nodes.find(e) != nodes.end() && nodes[e]->m_框节点 == nullptr) {
			m_框包含节点.push_back(nodes[e]);

			nodes[e]->m_框节点 = this;
		}
	}
	m_框包含节点名称.clear();
}

void C_节点基类::f_读取(FILE* f) {
	auto 文件块 = f_file_读取文件块(f);
	if (文件块.m_块类型 == E_节点工程文件块类型::e_工程文件块_节点) {
		const uint8* 下一次读取数据指针 = 文件块.m_data;

		下一次读取数据指针 = f_解宽字符串(m_Name, 下一次读取数据指针);
		下一次读取数据指针 = f_解字符串(m_ICO, 下一次读取数据指针);

		下一次读取数据指针 = f_文件块_取数据块(m_数据布局, 下一次读取数据指针);
		下一次读取数据指针 = f_文件块_取数据块(m_坐标, 下一次读取数据指针);
		下一次读取数据指针 = f_文件块_取数据块(m_冻结数据, 下一次读取数据指针);
		下一次读取数据指针 = f_文件块_取数据块(m_显示数据, 下一次读取数据指针);
		下一次读取数据指针 = f_文件块_取数据块(m_插座可编辑, 下一次读取数据指针);
		下一次读取数据指针 = f_prop_Load(m_启用, 下一次读取数据指针);


		uint32 num = 0;
		下一次读取数据指针 = f_文件块_取数据块(num, 下一次读取数据指针);
		for (uint32 i = 0; i < num; ++i) {
			std::wstring 框包含节点名称;
			下一次读取数据指针 = f_解宽字符串(框包含节点名称, 下一次读取数据指针);
			m_框包含节点名称.push_back(框包含节点名称);
		}
	}
	free(文件块.m_data);

	//m_Name = f_file_读取字符串(f);
	//
	//fread((uint32*)&m_数据布局, sizeof(uint32), 1, f);
	//fread(&m_坐标, sizeof(vec2), 1, f);
	//fread(&m_冻结数据, sizeof(bool), 1, f);
	//fread(&m_显示数据, sizeof(bool), 1, f);
	//fread(&m_插座可编辑, sizeof(bool), 1, f);
	//
	//m_ICO = f_读取字符串(f);
	//
	//f_prop_Load(m_启用, f);
}

void C_节点基类::f_写入(FILE* f) {
	auto 文件块 = f_file_构建文件块信息(E_节点工程文件块类型::e_工程文件块_节点, S_节点数据::g_文件版本号);
	S_UI8Array* 块 = (S_UI8Array*)f_core_array_new(0, sizeof(uint8));

	f_包宽字符串(块, m_Name);
	f_包字符串(块, m_ICO);
	//f_file_保存字符串(f, m_Name);

	f_core_array_push_back_block((S_Array*)块, (uint8*)&m_数据布局, sizeof(uint32));
	f_core_array_push_back_block((S_Array*)块, (uint8*)&m_坐标, sizeof(vec2));
	f_core_array_push_back_block((S_Array*)块, (uint8*)&m_冻结数据, sizeof(bool));
	f_core_array_push_back_block((S_Array*)块, (uint8*)&m_显示数据, sizeof(bool));
	f_core_array_push_back_block((S_Array*)块, (uint8*)&m_插座可编辑, sizeof(bool));
	f_prop_Save(m_启用, 块);


	uint32 num = m_框包含节点.size();
	f_文件块_写数据块(块, num);
	for (auto& e : m_框包含节点) {
		f_包宽字符串(块, e->m_Name);
	}


	f_file_保存文件块(f, 文件块, 块);
}


void C_节点基类::f_写入插座(FILE* f) {
	uint32 socketNum = m_inputs.size();
	fwrite(&socketNum, sizeof(uint32), 1, f);
	//cout << "写入插座 socketNum = " << socketNum << endl;
	auto* p_socket = m_inputs.data();
	//for (auto& s : m_inputs) {
	for (uint32 i = 0; i < socketNum; ++i) {
		fwrite(&p_socket[i]->m_Type, sizeof(E_值类型), 1, f);
		p_socket[i]->f_写入(f);
	}

	socketNum = m_outputs.size();
	fwrite(&socketNum, sizeof(uint32), 1, f);

	p_socket = m_outputs.data();
	//for (auto& s : m_outputs) {
	for (uint32 i = 0; i < socketNum; ++i) {
		fwrite(&p_socket[i]->m_Type, sizeof(E_值类型), 1, f);
		p_socket[i]->f_写入(f);
	}

}

void C_节点基类::f_读取插座(std::map<std::wstring, C_节点基类*>& nodes, FILE* f) {
	uint32 socketNum = 0;
	fread(&socketNum, sizeof(uint32), 1, f);

	for (uint32 i = 0; i < socketNum; ++i) {
		E_值类型 socketType = E_值类型::e_Type_None;
		fread(&socketType, sizeof(E_值类型), 1, f);

		C_插座基类* p_socket;
		if (i < m_inputs.size()) {
			p_socket = m_inputs[i];
			//if (p_socket->f_get接入的数据类型() != socketType) {
			if (p_socket->m_Type != socketType) {
				f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输入, i, socketType);
				p_socket = f_get输入插座(i);
			}
		}
		else {
			p_socket = f_su_创建节点后端插座(L"new socket", socketType);
			f_add插座(p_socket, E_插座方向::e_插座Type_输入);
		}

		p_socket->f_读取(f);
	}


	fread(&socketNum, sizeof(uint32), 1, f);
	uint16 输出插座Num = f_get输出插座Num();
	auto* p_socket = m_outputs.data();
	for (uint32 i = 0; i < socketNum; ++i) {
		E_值类型 socketType = E_值类型::e_Type_None;
		fread(&socketType, sizeof(E_值类型), 1, f);

		C_插座基类* p_socket;
		if (i < 输出插座Num) {
			p_socket = f_get输出插座(i);
			//if (p_socket->f_get接入的数据类型() != socketType) {
			if (p_socket->m_Type != socketType) {
				f_su_切换后端插座类型(this, E_插座方向::e_插座Type_输出, i, socketType);
				p_socket = f_get输出插座(i);
			}
		}
		else {
			p_socket = f_su_创建节点后端插座(L"new socket", socketType);
			f_add插座(p_socket, E_插座方向::e_插座Type_输出);
		}
		
		p_socket->f_读取(f);
	}
}


void C_节点基类::f_写入插座链接(FILE* f) {
	uint32 socketNum = m_inputs.size();
	auto* p_socket = m_inputs.data();

	fwrite(&socketNum, sizeof(uint32), 1, f);
	for (uint32 i = 0; i < socketNum; ++i) {
		uint16 linktNum = p_socket[i]->m_p当前输出插座绑定连接线.size();
		fwrite(&linktNum, sizeof(uint16), 1, f);

		for (auto& link : p_socket[i]->m_p当前输出插座绑定连接线) {
			int16 loc = link->m_插座out->m_pNode->f_get输出插座Loc(link->m_插座out);
			
			f_file_保存字符串(f, link->m_插座out->m_pNode->m_Name);
			fwrite(&loc, sizeof(int16), 1, f);
		}
	}
}

void C_节点基类::f_读取插座链接(FILE* f, std::map<std::wstring, C_节点基类*>& nodes) {
	uint32 socketNum = m_inputs.size();
	auto* p_socket = m_inputs.data();

	fread(&socketNum, sizeof(uint32), 1, f);
	for (uint32 i = 0; i < socketNum; ++i) {
		uint16 linktNum = 0;
		fread(&linktNum, sizeof(uint16), 1, f);

		for (uint32 k = 0; k < linktNum; ++k) {
			S_NodeLink* link = new S_NodeLink;
			wstring nodeName = f_file_读取字符串(f);

			int16 loc = 0;
			fread(&loc, sizeof(int16), 1, f);

			if (nodes.find(nodeName) != nodes.end()) {
				link->f_Link(p_socket[i], nodes[nodeName]->f_get输出插座(loc));
			}
			else {
				std::cout<<"插座读取链接未找到节点"<<std::endl;
			}
		}
		
	}
}

S_物体* C_节点基类::f_get虚拟体() {
	return (S_物体*)nullptr;
}


S_动画曲线组* C_节点基类::f_getAN曲线() {
	static S_动画曲线组* curve = f_an_创建曲线层();
	return curve;
}







static S_节点插座类型名称 gName;

std::string f_node_getDataTypeName(E_值类型 type) {
	gName.m_f16 = L"float16";

	std::string code;
	switch (type)
	{
	case e_Type_None:
		break;
	case e_Type_Operator:
		break;
	case e_Type_Enum:	code = "int32";
		break;
	case e_Type_Str:
		break;
	case e_Type_Bool:	code = "bool";
		break;
	case e_Type_LineText:
		break;
	case e_Type_F16:	code = "int16";
		break;
	case e_Type_F32:	code = "float32";
		break;
	case e_Type_F64:	code = "float64";
		break;
	case e_Type_F128:	code = "float128";
		break;
	case e_Type_I8:		code = "int8";
		break;
	case e_Type_I16:	code = "int16";
		break;
	case e_Type_I32:	code = "int32";
		break;
	case e_Type_I64:	code = "int64";
		break;
	case e_Type_I128:	code = "int128";
		break;
	case e_Type_UI4:	code = "uint64";
		break;
	case e_Type_UI8:	code = "uint8";
		break;
	case e_Type_UI16:	code = "uint16";
		break;
	case e_Type_UI32:	code = "uint32";
		break;
	case e_Type_UI64:	code = "uint64";
		break;
	case e_Type_UI128:	code = "uint128";
		break;
	case e_Type_Vec2:	code = "vec2";
		break;
	case e_Type_Vec3:	code = "vec3";
		break;
	case e_Type_Vec4:	code = "vec4";
		break;
	case e_Type_iVec2:	code = "ivec2";
		break;
	case e_Type_uVec2:	code = "uvec2";
		break;
	case e_Type_iVec3:	code = "ivec3";
		break;
	case e_Type_uVec3:	code = "uvec3";
		break;
	case e_Type_iVec4:	code = "ivec4";
		break;
	case e_Type_uVec4:	code = "uvec4";
		break;
	case e_Type_RGBA8:	code = "bvec4";
		break;
	case e_Type_RGBA16:
		break;
	case e_Type_RGBA32:
		break;
	case e_Type_Quat:	code = "vec4";
		break;
	case e_Type_Str_1D:
		break;
	case e_Type_Bool_Array1D:
		break;
	case e_Type_F32_Array1D:	code = "void*";
		break;
	case e_Type_F64_1D:	code = "void*";
		break;
	case e_Type_I8_1D:	code = DEF_S(S_I8Array);
		break;
	case e_Type_I32_1D:	code = DEF_S(S_I32Array);
		break;
	case e_Type_I64_Array1D:	code = "void*";
		break;
	case e_Type_UI8_Array1D:	code = "void*";
		break;
	case e_Type_UI32_1D:	code = DEF_S(S_UI32Array); break;
	case e_Type_UI32_2D:	code = DEF_S(S_UI32Array2D); break;
		
	case e_Type_Array:	code = DEF_S(S_Array);
		break;
	case e_Type_Vec3_Array1D:	code = "void*";
		break;
	case e_Type_Vec4_Array1D:	code = "void*";
		break;
	case e_Type_Quat_Array1D:	code = "void*";
		break;
	case e_Type_Mat2X2:	code = "void*";
		break;
	case e_Type_Mat3X3:	code = "void*";
		break;
	case e_Type_Mat4X4:	code = "Mat44f";
		break;
	case e_Type_2D曲线采样:
		break;
	case e_Type_2D曲线采样1D:
		break;
	case e_Type_Mesh: code = DEF_S(S_Mesh);
		break;
	case e_Type_Object: code = DEF_S(S_物体);
		break;
	case e_Type_Object_Array1D:
		break;
	case e_Type_Object_1D: code = DEF_S(S_OBArray);
		break;
	case e_Type_ObjectData:
		break;
	case e_Type_ParticleSystem:
		break;
	case e_Type_Scene:
		break;
	case e_Type_集合:
		break;
	case e_Type_体素:
		break;
	case e_Type_多边形:     code = DEF_S(S_多边形);
		break;
	case e_Type_多边形_1D:	code = DEF_S(S_多边形Array); break;
	case e_Type_多边形边:	code = DEF_S(S_边);
		break;
	case e_Type_多边形边1D:	code = DEF_S(S_边Array); break;
		
	case e_Type_多边形面:	code = "S_面";
		break;
	case e_Type_多边形面1D:
		break;
	case e_Type_面顶点索引:
		break;
	case e_Type_多边形元素:   code = DEF_S(S_多边形元素);
		break;
	case e_Type_多边形元素1D: code = DEF_S(S_多边形元素Array);
		break;
	case e_Type_RGB:
		break;
	case e_Type_RGBA:
		break;
	case e_Type_材质:	code = DEF_S(S_材质);
		break;
	case e_Type_材质1D:	code = DEF_S(S_MaterialArray);
		break;
	//case e_Type_图像:	code = DEF_S(S_MaterialArray);	break;
	case e_Type_纹理:	code = DEF_S(S_纹理);			break;
	case e_Type_纹理1D: code = DEF_S(S_TexArray);		break;
		

	case e_Type_GPU缓存1D:
		break;
	case e_Type_车轮:
		break;
	case e_Type_车辆:
		break;
	case e_Type_发射:
		break;
	case e_插座Type_物理材质:
		break;
	case e_插座Type_物理几何:
		break;
	case e_插座Type_物理体:
		break;
	case e_插座Type_物理平面:
		break;
	case e_插座Type_bl物体朝向:
		break;
	case e_插座Type_引用数据:	code = "void*";
		break;
	case e_插座Type_调试信息:
		break;
	case e_插座Type_动态转换:
		break;
	case e_插座Type_ArrayBegin:
		break;
	case e_插座Type_Str_2D:
		break;
	case e_插座Type_Str_3D:
		break;
	case e_插座Type_Str_4D:
		break;
	case e_Type_2D曲线:	code = "S_曲线";
		break;
	case e_插座Type_Array3D_Bool:
		break;
	case e_Type_UI32_FlagBits:
		break;
	case e_插座Type_I8_Array2D:
		break;
	
	case e_插座Type_I8_Array4D:
		break;
	case E_值类型::e_Type_Bool_1D:	code = DEF_S(S_BoolArray);
		break;
	case e_Type_F32_1D:	code = DEF_S(S_F32Array);
		break;
	case e_插座Type_F32_Array3D:
		break;
	case e_插座Type_Array4D_F32:
		break;
	case e_插座Type_I32_Array2D:
		break;
	case e_插座Type_I32_Array3D:
		break;
	case e_插座Type_I32_Array4D:
		break;
	case e_插座Type_UI32_Array2D:
		break;
	case e_插座Type_UI32_Array3D:
		break;
	case e_插座Type_UI32_Array4D:
		break;
	case e_插座Type_I64_Array2D:
		break;
	case e_插座Type_I64_Array3D:
		break;
	case e_插座Type_I64_Array4D:
		break;
	case e_插座Type_UI64_Array1D:
		break;
	case e_Type_Vec2_1D:	code = DEF_S(S_Vec2Array);
		break;
	case e_插座Type_Vec2_Array3D:
		break;
	case e_Type_iVec2_1D:	code = DEF_S(S_iVec2Array);
		break;

	case e_Type_uVec2_1D:	code = DEF_S(S_uVec2Array);
		break;

	case e_Type_Vec3_1D:	code = DEF_S(S_Vec3Array); break;
	case e_Type_Vec3_2D:	code = DEF_S(S_Vec3Array2D); break;

	case e_Type_iVec3_1D:	code = DEF_S(S_iVec3Array); break;
	case e_Type_iVec3_2D:	code = DEF_S(S_iVec3Array2D); break;
	
	case e_Type_Vec4_1D:	code = DEF_S(S_Vec4Array);
		break;
	case e_插座Type_Vec4_Array3D:
		break;
	case e_插座Type_Vec4_Array4D:
		break;
	case e_插座Type_Vec2i_Array2D:
		break;
	case e_过程纹理:
		break;
	case e_过程纹理_1D:
		break;
	case e_Type_Shader:
		break;
	//case e_插座Type_Vec4i_Array1D:
	//	break;
	case e_Type_Node:
		break;
	case e_Type_Widget:
		break;
	case e_Type_TexProp:
		break;
	case e_插座Type_Rect32f:
		break;
	case e_插座Type_Rect32f_Array1D:
		break;
	case e_Type_Cube_Array1D:
		break;
	case e_插座Type_Vec球:
		break;
	case e_Type_VecSphere_1D:
		break;
	case e_Type_Bounding:
		break;
	case e_Type_Bounding_Array1D:
		break;
	case e_插座Type_Line:
		break;
	case e_插座Type_Line_Array1D:
		break;
	case e_Type_VN:
		break;
	case e_Type_VN_Array1D:
		break;
	case e_插座Type_Mat2X2_Array1D:
		break;
	case e_插座Type_Mat3X3_Array1D:
		break;
	case e_Type_Mat4X4_1D:	code = DEF_S(S_Mat44Array); break;
	case e_Type_Mat4X4_Array1D:	code = "void*";
		break;
	
		break;
	case e_插座Type_Mat4X4_Array3D:
		break;
	case e_插座Type_Mat4X4_Array4D:
		break;
	case e_插座Type_MapiVec3_Uint32_Array1D:
		break;
	case e_插座Type_MapiVec3_Uint32_Array2D:
		break;
	case e_插座Type_Uint64Map_Uint32_Array2D:
		break;
	case e_Type_Tranform_Array1D:
		break;
	case e_Type_Mesh_1D:
		break;
	case e_插座Type_Mesh_Array2D:
		break;
	case e_Type_元素选择1D:
		break;
	case e_Type_元素选择:
		break;
	case e_插座Type_根对象_1D:
		break;
	case e_插座Type_ObjectData_Array1D:
		break;
	case e_Type_骨架:
		break;
	case e_Type_骨架_Array1D:
		break;
	case e_Type_骨骼:
		break;
	case e_Type_骨骼_Array1D:
		break;
	case e_Type_IK:
		break;
	case e_Type_IK_Array1D:
		break;
	case e_插座Type_VectorParticle:
		break;
	case e_插座Type_VectorScene:
		break;
	case e_插座Type_字体_1D:
		break;
	case e_插座Type_物理解算器:
		break;
	case e_插座Type_车轮_Array1D:
		break;
	case e_插座Type_车辆_Array1D:
		break;
	case e_插座Type_物理材质_Array1D:
		break;
	case e_插座Type_物理几何_Array1D:
		break;
	case e_插座Type_物理体_Array1D:
		break;
	case e_插座Type_物理平面_Array1D:
		break;
	case e_Type_Array元素:
		break;
	case e_插座Type_通用取:
		break;
	case e_插座Type_八叉树:
		break;
	case e_插座Type_树路径:
		break;
	case e_Type_Mesh_点:
		break;
	case e_Type_Mesh_线:
		break;
	case e_Type_Mesh_面中心:
		break;
	case e_Type_Mesh_点1D:
		break;
	case e_Type_Mesh_线1D:
		break;
	case e_Type_Mesh_面中心1D:
		break;
	case e_Type_路径:
		break;
	case e_Type_MapPtr:
		break;
	case e_Type_MapPtr_Array1D:
		break;
	case e_Type_PropContainer:
		break;
	case e_Type_PropList:
		break;
	case e_Type_LayoutBegin:
		break;
	case e_Type_LayoutList:
		break;
	case e_Type_LayoutMesh:
		break;
	case e_Type_LayoutTypeEdit:
		break;
	case e_Type_LayoutEnd:
		break;
	case e_Type_End:
		break;
	default:
		break;
	}

	assert(code.size());
	return code;
}


void f_node_销毁程序集(class C_节点树* 子集节点树) {
	if(!子集节点树) return;

	f_JIT_销毁(子集节点树->m_程序集, (E_JIT方式)f_prop_enum(子集节点树->m_编译方式));
	子集节点树->m_程序集 = 0;
	子集节点树->m_开始编译 = false;
}

void f_node_移除插座准备销毁(C_插座基类* socket) {
	g待销毁插座.push_back(socket);
}

void f_node_销毁插座() {
	for (auto& e : g待销毁插座) {
		delete e;
	}
	g待销毁插座.clear();
}

